from bot.enterprise_wechat_gpt.agent.generate_final_utter import *
from bot.enterprise_wechat_gpt.agent.split_utter_agent import *
from bot.enterprise_wechat_gpt.agent.transfer_judge_agent import judge_transfer
from bot.enterprise_wechat_gpt.util.check_transfer import (check_api_return, complex_situation, check_situation)
from bot.enterprise_wechat_gpt.util.user_info_util import *


def total_process_test(raw_conversation_history, user_say, user_id='User_abc'):
    local_data.user_id = user_id
    local_data.msg = user_say
    start_time = time.time()

    res_total = {}
    conversation_history = clean_conversation_history(raw_conversation_history)
    res_total['历史对话'] = conversation_history

    loops = get_loops()

    user_question, user_situation = get_user_question_and_user_situation(conversation_history, loops)
    #logging.info(f"userId:[{user_id}] 1.获取用户问题和情境耗时：{time.time() - start_time}s "
    #             f"\n【用户问题】：{user_question} \n【用户情境】：{user_situation}")

    res_total["用户问题"] = user_question
    res_total["用户情境"] = user_situation

    # 判断用户情境是否转人
    if env_str == 'dev' or env_str == 'prod':
        t = check_situation(user_question, user_situation, user_id)
        if t['transfer_flag']:
            res_total['最终话术'] = f"发生转人操作，转人原因：{t['transfer_reason']}"
            res_total['是否转人'] = True
            # conversation_history_util.add_system_msg(user_id, res_total['最终话术'])
            #logging.info(f"userId:[{user_id}] 发生转人操作 转人原因: {t['transfer_reason']}")
            return res_total
        t = complex_situation(user_situation, user_question, user_id)
        if t['transfer_flag']:
            res_total['最终话术'] = f"发生转人操作，转人原因：{t['transfer_reason']}"
            res_total['是否转人'] = True
            # conversation_history_util.add_system_msg(user_id, res_total['最终话术'])
            #logging.info(f"userId:[{user_id}] 发生转人操作 转人原因: {t['transfer_reason']}")
            return res_total


    multi_knowledge = search_knowledge(user_question, user_situation, user_say)
    tasks_2 = [get_solution(conversation_history, multi_knowledge, user_question, user_situation),
               get_sales_skill(conversation_history, user_question, user_situation),]
               #self_utter_generate(conversation_history[-10:], user_id)]
    res_knowledge_solution, sales_skill_name = loops.run_until_complete(asyncio.gather(*tasks_2))
    #res_knowledge_solution, sales_skill_name, self_model_utter = loops.run_until_complete(asyncio.gather(*tasks_2))


    knowledge_solution_set = get_knowledge_solution_set(search_knowledge(res_knowledge_solution))
    knowledge_solution_set.update({len(knowledge_solution_set)+1: res_knowledge_solution})
    res_total["Question-search知识"] = multi_knowledge
    res_total["解决方案"] = res_knowledge_solution
    res_total["Solution-search知识集"] = knowledge_solution_set
    #res_total["自训大模型-话术"] = self_model_utter

    sales_skill_utter_set = get_sales_skill_utter(sales_skill_name)
    logging.info(f"userId:[{user_id}] 【方案前-搜索知识库知识】：{multi_knowledge} \n【解决方案】：{res_knowledge_solution} \n【解决方案-搜索知识库】：{knowledge_solution_set}"
                 f"\n【销售技巧】：{sales_skill_name} \n【销售技巧话术集】：{sales_skill_utter_set}")
                 #f"\n【销售技巧】：{sales_skill_name} \n【销售技巧话术集】：{sales_skill_utter_set}\n 【自训大模型-话术】：{self_model_utter}")

    res_total["销售技巧"] = sales_skill_name
    res_total["技巧话术集"] = sales_skill_utter_set


    final_utter = loops.run_until_complete(
        get_utter_replay(conversation_history, knowledge_solution_set, sales_skill_utter_set, user_id))
        #get_utter_replay(conversation_history, knowledge_solution_set, sales_skill_utter_set, self_model_utter, user_id))
    res_total["最终话术"] = final_utter


    times = 1
    retry = check_api_return(final_utter)  # 检测话术生成结果 是否合法，True不合法重试3次；3次后仍然不合法 转人
    while times < 3 and retry:
        final_utter = loops.run_until_complete(
            get_utter_replay(conversation_history, knowledge_solution_set, sales_skill_utter_set, user_id))
            #get_utter_replay(conversation_history, knowledge_solution_set, sales_skill_utter_set, self_model_utter, user_id))
        retry = check_api_return(final_utter)
        times += 1
    retry = check_api_return(final_utter)
    if retry:   # 3次后仍然不合法 转人
        res_total['最终话术'] = f"发生转人操作，转人原因：话术生成不合法"
        res_total['是否转人'] = True
        return res_total

    conversation_history_ = conversation_history[:]
    conversation_history_.append({ASSISTANT: final_utter})
    transfer_info = loops.run_until_complete(judge_transfer(conversation_history_))

    transfer_flag = transfer_info.get('transfer_flag', False)
    res_total['是否转人'] = transfer_flag
    if transfer_flag:
        transfer_reason = transfer_info.get('transfer_reason', '')
        res_total['最终话术'] = "发生转人操作 转人原因: " + transfer_reason

    return res_total





def total_process(raw_conversation_history, user_say, user_id='User_abc'):
    local_data.user_id = user_id
    local_data.msg = user_say
    start_time = time.time()

    res_total = {}
    conversation_history = clean_conversation_history(raw_conversation_history)

    loops = get_loops()

    user_question, user_situation = get_user_question_and_user_situation(conversation_history, loops)
    logging.info(f"userId:[{user_id}] 1.获取用户问题和情境耗时：{time.time() - start_time}s "
                 f"\n【用户问题】：{user_question} \n【用户情境】：{user_situation}")

    has_coupon = user_has_coupon(local_data.wx_id)

    res_total["用户问题"] = user_question
    # res_total["用户情境"] = user_situation

    # 判断用户情境是否转人
    if env_str == 'dev' or env_str == 'prod':
        t = check_situation(user_question, user_situation, user_id)
        if t['transfer_flag']:
            res_total['最终话术'] = f"发生转人操作，转人原因：{t['transfer_reason']}"
            res_total['是否转人'] = True
            # conversation_history_util.add_system_msg(user_id, res_total['最终话术'])
            logging.info(f"userId:[{user_id}] 发生转人操作 转人原因: {t['transfer_reason']}")
            return res_total
        t = complex_situation(user_situation, user_question, user_id)
        if t['transfer_flag']:
            res_total['最终话术'] = f"发生转人操作，转人原因：{t['transfer_reason']}"
            res_total['是否转人'] = True
            # conversation_history_util.add_system_msg(user_id, res_total['最终话术'])
            logging.info(f"userId:[{user_id}] 发生转人操作 转人原因: {t['transfer_reason']}")
            return res_total


    t2_start_time = time.time()
    # 2. 解决方案和销售技巧
    multi_knowledge = search_knowledge(user_question, user_situation, user_say)
    user_situation = get_new_situation(has_coupon, user_situation)
    res_total["用户情境"] = user_situation
    tasks_2 = [get_solution(conversation_history, multi_knowledge, user_question, user_situation),
               get_sales_skill(conversation_history, user_question, user_situation, has_coupon)]
    res_knowledge_solution, sales_skill_name = loops.run_until_complete(asyncio.gather(*tasks_2))
    logging.info(f"userId:[{user_id}] 2.解决方案和销售技巧耗时：{time.time() - t2_start_time}s")

    knowledge_solution_set = get_knowledge_solution_set(search_knowledge(res_knowledge_solution))
    knowledge_solution_set.update({len(knowledge_solution_set)+1: res_knowledge_solution})
    res_total["Question-search知识"] = multi_knowledge
    res_total["解决方案"] = res_knowledge_solution
    res_total["Solution-search知识集"] = knowledge_solution_set

    sales_skill_utter_set = get_sales_skill_utter(sales_skill_name)
    logging.info(f"userId:[{user_id}] 【方案前-搜索知识库知识】：{multi_knowledge} \n【解决方案】：{res_knowledge_solution} \n【解决方案-搜索知识库】：{knowledge_solution_set}"
                 f"\n【销售技巧】：{sales_skill_name} \n【销售技巧话术集】：{sales_skill_utter_set}")

    res_total["销售技巧"] = sales_skill_name
    res_total["技巧话术集"] = sales_skill_utter_set
    t3_start_time = time.time()
    # 3. 话术生成
    final_utter = loops.run_until_complete(
        get_utter_replay(conversation_history, knowledge_solution_set, sales_skill_utter_set, user_id, has_coupon))

    logging.info(f"userId:[{user_id}] 3.话术生成耗时：{time.time() - t3_start_time}s")

    if env_str == 'dev' or env_str == 'prod':
        times = 1
        retry = check_api_return(final_utter)  # 检测话术生成结果 是否合法，True不合法重试3次；3次后仍然不合法 转人
        while times < 3 and retry:
            final_utter = loops.run_until_complete(
                get_utter_replay(conversation_history, knowledge_solution_set, sales_skill_utter_set, user_id, has_coupon))
            retry = check_api_return(final_utter)
            times += 1
        retry = check_api_return(final_utter)
        if retry:   # 3次后仍然不合法 转人
            res_total['最终话术'] = f"发生转人操作，转人原因：话术生成不合法"
            res_total['是否转人'] = True
            # conversation_history_util.add_system_msg(user_id, res_total['最终话术'])
            logging.info(f"userId:[{user_id}] 发生转人操作 转人原因: 话术生成不合法")
            return res_total

    if env_str == 'dev' or env_str == 'prod':
        conversation_history.append({ASSISTANT: final_utter})
        if len(final_utter) > 100 and '\n\n' not in final_utter:
            # 大于100个字，且没有两个换行符，进行分句
            logging.info(f"userId:[{user_id}] 话术长度大于100，进行分句")
            tasks_3 = [judge_transfer(conversation_history, has_coupon), get_split_utter(final_utter)]
            transfer_info, final_utter = loops.run_until_complete(asyncio.gather(*tasks_3))
        else:
            transfer_info = loops.run_until_complete(judge_transfer(conversation_history, has_coupon))
        transfer_flag = transfer_info.get('transfer_flag', False)
        if transfer_flag:
            transfer_reason = transfer_info.get('transfer_reason', '')
            logging.info(f"userId:[{user_id}] 发生转人操作 转人原因: {transfer_reason}")
            res_total['最终话术'] = "发生转人操作 转人原因: " + transfer_reason
            res_total['是否转人'] = transfer_flag
        else:
            res_total["最终话术"] = final_utter
    else:
        res_total["最终话术"] = final_utter
    logging.info(f"userId:[{user_id}] 销售：{final_utter}")
    return res_total


def get_new_situation(has_coupon, user_situation):
    coupon_status = f"系统后台显示用户是否有优惠券：{'是' if has_coupon else '否'}"
    if user_situation:
        user_situation = coupon_status + "｜" + user_situation
    else:
        user_situation = coupon_status
    return user_situation


def get_loops():
    new_loop = asyncio.new_event_loop()
    asyncio.set_event_loop(new_loop)
    return asyncio.get_event_loop()


def get_user_question_and_user_situation(conversation_history, loops):
    tasks_1 = [get_user_question(conversation_history), get_user_situation(conversation_history)]
    uq, us = loops.run_until_complete(asyncio.gather(*tasks_1))
    return uq, us


# 根据解决方案-搜索知识库 找3条知识
def get_knowledge_solution_set(kn_sol_set):
    return {(i + 1): kn_sol_set[i]['答案'] for i in
            range(len(kn_sol_set))}
